/*
 * EditorFrame.java
 *
 * Created on 4 de Abril de 2007, 18:18
 */

package org.gpp.proj1.map.editor;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.ListModel;
import javax.swing.SpinnerNumberModel;

/**
 *
 * @author  Gustavo
 */
public class EditorFrame extends javax.swing.JFrame implements BlockConfigurationHandler, MapCreationHandler {
    
    /**
     *
     */
    private static final long serialVersionUID = -5892902475752532491L;
    
    private BlockPanel blockPanel;
    private IndexedImage[][] textures;
    private DecorationImage[] decorations;
    
    private boolean height_modification;
    private boolean texture_modification;
    private boolean decoration_modification;
    private boolean clear_modification;
    
    /** Creates new form EditorFrame */
    public EditorFrame() {
        initComponents();
        this.setLocationRelativeTo(null);
        
        this.scrollPane.setMaximumSize(this.scrollPane.getSize());
        
        this.height_modification = false;
        this.texture_modification = false;
        this.decoration_modification = false;
        this.clear_modification = false;
        this.blockPanel = null;
    }
    
    private ListModel getTexturesList() {
        
        DefaultListModel model = new DefaultListModel();
        List<ImageIcon> list = this.loadTextures();
        for (ImageIcon i : list) {
            model.addElement(i);
        }
        
        return model;
    }
    
    private ListModel getDecorationsList() {
        
        DefaultListModel model = new DefaultListModel();
        List<ImageIcon> list = this.loadDecorations();
        for (ImageIcon i : list) {
            model.addElement(i);
        }
        
        return model;
    }
    
    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
    private void initComponents() {
        topSideButtonGroup = new javax.swing.ButtonGroup();
        saveFileChooser = new javax.swing.JFileChooser();
        decorationRotationButtonGroup = new javax.swing.ButtonGroup();
        toolsPanel = new javax.swing.JPanel();
        texturesPanel = new javax.swing.JPanel();
        jScrollPane1 = new javax.swing.JScrollPane();
        texturesList = new javax.swing.JList();
        topRadioButton = new javax.swing.JRadioButton();
        sideRadioButton = new javax.swing.JRadioButton();
        decorationsPanel = new javax.swing.JPanel();
        jScrollPane2 = new javax.swing.JScrollPane();
        decorationsList = new javax.swing.JList();
        degree0RadioButton = new javax.swing.JRadioButton();
        degree90RadioButton = new javax.swing.JRadioButton();
        degree180RadioButton = new javax.swing.JRadioButton();
        degree270RadioButton = new javax.swing.JRadioButton();
        clearDecorationToggleButton = new javax.swing.JToggleButton();
        heightPanel = new javax.swing.JPanel();
        heightToggleButton = new javax.swing.JToggleButton();
        heightSpinner = new javax.swing.JSpinner();
        scrollPane = new javax.swing.JScrollPane();
        menuBar = new javax.swing.JMenuBar();
        fileMenu = new javax.swing.JMenu();
        newMenuItem = new javax.swing.JMenuItem();
        openMenuItem = new javax.swing.JMenuItem();
        saveMenuItem = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JSeparator();
        exitMenuItem = new javax.swing.JMenuItem();
        optionsMenu = new javax.swing.JMenu();
        renderMenu = new javax.swing.JMenu();
        previewMenuItem = new javax.swing.JMenuItem();
        helpMenu = new javax.swing.JMenu();
        contentsMenuItem = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JSeparator();
        aboutMenuItem = new javax.swing.JMenuItem();

        saveFileChooser.setAcceptAllFileFilterUsed(false);
        saveFileChooser.setCurrentDirectory(new java.io.File("C:\\Arquivos de programas\\netbeans-5.5\\.\\res\\map"));
        saveFileChooser.setDialogTitle("Save map");
        saveFileChooser.setDialogType(javax.swing.JFileChooser.SAVE_DIALOG);
        saveFileChooser.setFileFilter(new SaveMapFileFilter());
        saveFileChooser.setFileHidingEnabled(true);

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("SomeRobotGame - Map Editor");
        setResizable(false);
        texturesPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Textures"));
        texturesList.setModel(getTexturesList());
        texturesList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        texturesList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                texturesListValueChanged(evt);
            }
        });

        jScrollPane1.setViewportView(texturesList);

        topSideButtonGroup.add(topRadioButton);
        topRadioButton.setSelected(true);
        topRadioButton.setText("Top");
        topRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        topRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        topSideButtonGroup.add(sideRadioButton);
        sideRadioButton.setText("Side");
        sideRadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        sideRadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        org.jdesktop.layout.GroupLayout texturesPanelLayout = new org.jdesktop.layout.GroupLayout(texturesPanel);
        texturesPanel.setLayout(texturesPanelLayout);
        texturesPanelLayout.setHorizontalGroup(
            texturesPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(texturesPanelLayout.createSequentialGroup()
                .add(topRadioButton)
                .add(31, 31, 31)
                .add(sideRadioButton)
                .addContainerGap(66, Short.MAX_VALUE))
            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE)
        );
        texturesPanelLayout.setVerticalGroup(
            texturesPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(texturesPanelLayout.createSequentialGroup()
                .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 130, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(texturesPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
                    .add(topRadioButton)
                    .add(sideRadioButton))
                .addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        decorationsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Decorations"));
        decorationsList.setModel(getDecorationsList());
        decorationsList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        decorationsList.addListSelectionListener(new javax.swing.event.ListSelectionListener() {
            public void valueChanged(javax.swing.event.ListSelectionEvent evt) {
                decorationsListValueChanged(evt);
            }
        });

        jScrollPane2.setViewportView(decorationsList);

        decorationRotationButtonGroup.add(degree0RadioButton);
        degree0RadioButton.setSelected(true);
        degree0RadioButton.setText("0\u00ba");
        degree0RadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        degree0RadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        decorationRotationButtonGroup.add(degree90RadioButton);
        degree90RadioButton.setText("90\u00ba");
        degree90RadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        degree90RadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        decorationRotationButtonGroup.add(degree180RadioButton);
        degree180RadioButton.setText("180\u00ba");
        degree180RadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        degree180RadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        decorationRotationButtonGroup.add(degree270RadioButton);
        degree270RadioButton.setText("270\u00ba");
        degree270RadioButton.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        degree270RadioButton.setMargin(new java.awt.Insets(0, 0, 0, 0));

        clearDecorationToggleButton.setText("Clear");
        clearDecorationToggleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                clearDecorationToggleButtonActionPerformed(evt);
            }
        });

        org.jdesktop.layout.GroupLayout decorationsPanelLayout = new org.jdesktop.layout.GroupLayout(decorationsPanel);
        decorationsPanel.setLayout(decorationsPanelLayout);
        decorationsPanelLayout.setHorizontalGroup(
            decorationsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(jScrollPane2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 169, Short.MAX_VALUE)
            .add(decorationsPanelLayout.createSequentialGroup()
                .add(decorationsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(degree0RadioButton)
                    .add(degree180RadioButton))
                .add(38, 38, 38)
                .add(decorationsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(degree270RadioButton)
                    .add(degree90RadioButton))
                .add(84, 84, 84))
            .add(decorationsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(clearDecorationToggleButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE)
                .addContainerGap())
        );
        decorationsPanelLayout.setVerticalGroup(
            decorationsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(decorationsPanelLayout.createSequentialGroup()
                .add(jScrollPane2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 130, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(decorationsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(decorationsPanelLayout.createSequentialGroup()
                        .add(degree0RadioButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(degree180RadioButton))
                    .add(decorationsPanelLayout.createSequentialGroup()
                        .add(degree90RadioButton)
                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                        .add(degree270RadioButton)))
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 25, Short.MAX_VALUE)
                .add(clearDecorationToggleButton))
        );

        heightPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Height"));
        heightToggleButton.setText("Modify height");
        heightToggleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                heightToggleButtonActionPerformed(evt);
            }
        });

        heightSpinner.setModel(new SpinnerNumberModel(0, 0, EditorProperties.getInstance().max_block_height, 1));
        heightSpinner.setRequestFocusEnabled(false);

        org.jdesktop.layout.GroupLayout heightPanelLayout = new org.jdesktop.layout.GroupLayout(heightPanel);
        heightPanel.setLayout(heightPanelLayout);
        heightPanelLayout.setHorizontalGroup(
            heightPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(heightPanelLayout.createSequentialGroup()
                .addContainerGap()
                .add(heightPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
                    .add(heightSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 72, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                    .add(heightToggleButton, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 149, Short.MAX_VALUE))
                .addContainerGap())
        );
        heightPanelLayout.setVerticalGroup(
            heightPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(heightPanelLayout.createSequentialGroup()
                .add(heightSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .add(heightToggleButton))
        );

        org.jdesktop.layout.GroupLayout toolsPanelLayout = new org.jdesktop.layout.GroupLayout(toolsPanel);
        toolsPanel.setLayout(toolsPanelLayout);
        toolsPanelLayout.setHorizontalGroup(
            toolsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(texturesPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(decorationsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 185, Short.MAX_VALUE)
            .add(heightPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        toolsPanelLayout.setVerticalGroup(
            toolsPanelLayout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(toolsPanelLayout.createSequentialGroup()
                .add(texturesPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(decorationsPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(heightPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(86, Short.MAX_VALUE))
        );

        scrollPane.setFocusable(false);
        scrollPane.setRequestFocusEnabled(false);

        fileMenu.setText("File");
        newMenuItem.setText("New");
        newMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                newMenuItemActionPerformed(evt);
            }
        });

        fileMenu.add(newMenuItem);

        openMenuItem.setText("Open...");
        fileMenu.add(openMenuItem);

        saveMenuItem.setText("Save...");
        saveMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveMenuItemActionPerformed(evt);
            }
        });

        fileMenu.add(saveMenuItem);

        fileMenu.add(jSeparator1);

        exitMenuItem.setText("Exit");
        exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exitMenuItemActionPerformed(evt);
            }
        });

        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        optionsMenu.setText("Options");
        menuBar.add(optionsMenu);

        renderMenu.setText("Render");
        previewMenuItem.setText("Preview...");
        renderMenu.add(previewMenuItem);

        menuBar.add(renderMenu);

        helpMenu.setText("Help");
        contentsMenuItem.setText("Contents");
        helpMenu.add(contentsMenuItem);

        helpMenu.add(jSeparator2);

        aboutMenuItem.setText("About");
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        setJMenuBar(menuBar);

        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(layout.createSequentialGroup()
                .add(toolsPanel, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
                .add(scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 736, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
            .add(toolsPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .add(scrollPane, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 617, Short.MAX_VALUE)
        );
        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void clearDecorationToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearDecorationToggleButtonActionPerformed

        if (this.clearDecorationToggleButton.isSelected()) {
            this.texturesList.clearSelection();
            this.decorationsList.clearSelection();
            
            this.clear_modification = true;
            
            this.setEnabledPicturePanels(false, true);
            this.setEnabledHeightPanel(false);
        } else {
            this.clear_modification = false;
            this.setEnabledPicturePanels(true, true);
            this.setEnabledHeightPanel(true);
        }
    }//GEN-LAST:event_clearDecorationToggleButtonActionPerformed

    private void decorationsListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_decorationsListValueChanged

        if (this.decorationsList.getSelectedIndex() == -1) {
            this.decoration_modification = false;
        }
        else {
            this.decoration_modification = true;
            this.texturesList.clearSelection();
        }
    }//GEN-LAST:event_decorationsListValueChanged

    private void saveMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveMenuItemActionPerformed
        try {
            int resp = this.saveFileChooser.showSaveDialog(this);
            
            if (resp == JFileChooser.CANCEL_OPTION) {                
                return;
            }

            if (resp == JFileChooser.ERROR_OPTION) {
                // TODO colocar a causa verdadeira do erro
                JOptionPane.showMessageDialog(this, "Error during save.", "Error", JOptionPane.ERROR_MESSAGE);
            }
            
            if (resp == JFileChooser.APPROVE_OPTION) {

                File f = this.saveFileChooser.getSelectedFile();
                if (new SaveMapFileFilter().accept(f)) {
                    this.saveMapFile(f);
                } else {
                    JOptionPane.showMessageDialog(this, "Invalid file name.", "Error", JOptionPane.ERROR_MESSAGE);
                }
            }
        }
        catch (Exception e) {
            JOptionPane.showMessageDialog(this, "Error during save.", "Error", JOptionPane.ERROR_MESSAGE);
        }
    }//GEN-LAST:event_saveMenuItemActionPerformed

    private void texturesListValueChanged(javax.swing.event.ListSelectionEvent evt) {//GEN-FIRST:event_texturesListValueChanged
        
        if (this.texturesList.getSelectedIndex() == -1) {
            this.texture_modification = false;
        }
        else {
            this.texture_modification = true;
            this.decorationsList.clearSelection();
        }
    }//GEN-LAST:event_texturesListValueChanged

    private void heightToggleButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_heightToggleButtonActionPerformed
        
        if (this.heightToggleButton.isSelected()) {
            this.texturesList.clearSelection();
            this.decorationsList.clearSelection();
            
            this.height_modification = true;
            this.setEnabledPicturePanels(false, false);
        }
        else {
            this.height_modification = false;
            this.setEnabledPicturePanels(true, false);
        }
    }//GEN-LAST:event_heightToggleButtonActionPerformed

    private void newMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_newMenuItemActionPerformed

        new NewMapDialog(this, true, this, this.texturesList.getModel()).setVisible(true);
    }//GEN-LAST:event_newMenuItemActionPerformed

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        System.exit(0);
    }//GEN-LAST:event_exitMenuItemActionPerformed
    
    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new EditorFrame().setVisible(true);
            }
        });
    }

    public void setConfiguration(Block clicked) {
        
        if (this.height_modification) {
            clicked.setBlockHeight((Integer)this.heightSpinner.getValue());
        }
        else if (this.texture_modification) {
            
            if (this.topRadioButton.isSelected()) {
                clicked.setTopTexture(this.textures[this.texturesList.getSelectedIndex()][0]);
            }
            else if (this.sideRadioButton.isSelected()) {
                clicked.setSideTexture(this.textures[this.texturesList.getSelectedIndex()][1]);
            }
        }
        else if (this.decoration_modification) {
            clicked.setDecoration(this.decorations[this.decorationsList.getSelectedIndex()], this.getRotation());
        }
        else if (this.clear_modification) {
            clicked.setDecoration(null, 0);
        } 
    }

    private List<ImageIcon> loadTextures() {
        
        List<ImageIcon> l = new ArrayList<ImageIcon>();
        File[] files = TextureLoader.listTextureFiles(EditorProperties.getInstance().texture_list_file);
        this.textures = new IndexedImage[files.length][2];
        
        int side = EditorProperties.getInstance().block_side;
        int quarterSide = EditorProperties.getInstance().quarter_block_side;
        int listTextureSide = EditorProperties.getInstance().list_image_side;

        for ( int i = 0; i < files.length; i++) {
            try {
                ImageIcon icon = new ImageIcon( files[i].toURL() );

                Image sized = new BufferedImage(listTextureSide, listTextureSide, BufferedImage.TYPE_INT_RGB);
                sized.getGraphics().drawImage(icon.getImage(), 0, 0, listTextureSide, listTextureSide, this);

                IndexedImage topTexture = new IndexedImage(new BufferedImage(side - 2, side - 2, BufferedImage.TYPE_INT_RGB), (byte)i);
                topTexture.getImage().getGraphics().drawImage(icon.getImage(), 0, 0, side - 2, side - 2, this);
                IndexedImage sideTexture = new IndexedImage(new BufferedImage(quarterSide, quarterSide, BufferedImage.TYPE_INT_RGB), (byte)i);
                sideTexture.getImage().getGraphics().drawImage(icon.getImage(), 0, 0, quarterSide, quarterSide, this);
                
                this.textures[i][0] = topTexture;
                this.textures[i][1] = sideTexture;
                
                icon = new ImageIcon(sized);
                l.add(icon);
                
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            }
        }

        return l;
    }

    private List<ImageIcon> loadDecorations() {
        
        List<ImageIcon> l = new ArrayList<ImageIcon>();
        Map<File, String> files = TextureLoader.listDecorationFiles(EditorProperties.getInstance().decoration_list_file);
        this.decorations = new DecorationImage[files.size()];
        
        int side = EditorProperties.getInstance().block_side;
        int listTextureSide = EditorProperties.getInstance().list_image_side;
        
        int index = 0;
        for (Map.Entry<File, String> entry : files.entrySet()) {
            try {
                ImageIcon icon = new ImageIcon( entry.getKey().toURL() );

                Image sized = new BufferedImage(listTextureSide, listTextureSide, BufferedImage.TYPE_INT_RGB);
                sized.getGraphics().drawImage(icon.getImage(), 0, 0, listTextureSide, listTextureSide, this);

                DecorationImage decoration = new DecorationImage(new BufferedImage(side - 2, side - 2, BufferedImage.TYPE_INT_ARGB), entry.getValue());
                decoration.getImage().getGraphics().drawImage(icon.getImage(), 0, 0, side - 2, side - 2, this);

                this.decorations[index] = decoration;
                                
                icon = new ImageIcon(sized);
                l.add(icon);
                
                index++;
                
            } catch (MalformedURLException ex) {
                ex.printStackTrace();
            }
        }

        return l;
    }

    private void setEnabledPicturePanels(boolean b, boolean excludeButtons) {
        
        this.texturesList.setEnabled(b);

        this.decorationsList.setEnabled(b);
        if (!excludeButtons) this.clearDecorationToggleButton.setEnabled(b);
    }

    private void saveMapFile(File f) {
        PrintWriter pw = null;
        try {
            pw = new PrintWriter(f);
            
            pw.println("# Dimensions");
            pw.println(this.blockPanel.getMapWidth() + " " + this.blockPanel.getMapLenght());
            
            pw.println("# Heights");
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    pw.print(this.blockPanel.getBlocks()[l][c].getBlockHeight() + " ");
                }
                pw.println();
            }
            
            pw.println("# Modifiers");
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    pw.print("15 ");
                }
                pw.println();
            }
            
            pw.println("# Top textures");
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    pw.print(this.blockPanel.getBlocks()[l][c].getTopTexture().getIndex() + " ");
                }
                pw.println();
            }
            
            pw.println("# Side textures");
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    pw.print(this.blockPanel.getBlocks()[l][c].getSideTexture().getIndex() + " ");
                }
                pw.println();
            }
            
            pw.println("# Decorations");
            int decorationsNumber = 0;
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    if (this.blockPanel.getBlocks()[l][c].isDecorated()) {
                        decorationsNumber++;
                    }
                }
            }
            pw.println(decorationsNumber);
            
            for (int l = 0; l < this.blockPanel.getBlocks().length; l++) {
                for (int c = 0; c < this.blockPanel.getBlocks()[l].length; c++) {
                    if (this.blockPanel.getBlocks()[l][c].isDecorated()) {
                        pw.println(l + " " + c + " " + this.blockPanel.getBlocks()[l][c].getDecoration().getModel() + " -1 " + "1.0 " +  "0.0 " + "0.0 " + this.blockPanel.getBlocks()[l][c].getDecorationRotationPiRadians());
                    }
                }
            }
            
            pw.flush();
        }
        catch (FileNotFoundException ex) {
            // TODO throw Exception
        }
        finally {
            if (pw != null) {
                pw.close();
            }
        }        
    }

    public void createMap(int width, int length, int height, int topTextureIndex, int sideTextureIndex) {

        this.blockPanel = new BlockPanel(width, length, height, this.textures[topTextureIndex][0], this.textures[sideTextureIndex][1], this);
        this.scrollPane.setViewportView(blockPanel);
        this.scrollPane.setSize(this.scrollPane.getMaximumSize());

        if (blockPanel.getWidth() < this.scrollPane.getWidth()) {
            this.scrollPane.setSize(blockPanel.getWidth(), scrollPane.getHeight());
        }
        
        if (blockPanel.getHeight() < this.scrollPane.getHeight()) {
            this.scrollPane.setSize(scrollPane.getWidth(), blockPanel.getHeight());
        }
    }

    private void setEnabledHeightPanel(boolean b) {
        this.heightToggleButton.setEnabled(b);
    }

    private int getRotation() {
        return this.degree0RadioButton.isSelected() ? 0 :
               this.degree90RadioButton.isSelected() ? 90 :
               this.degree180RadioButton.isSelected() ? 180 :
               this.degree270RadioButton.isSelected() ? 270 : 0;
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem aboutMenuItem;
    private javax.swing.JToggleButton clearDecorationToggleButton;
    private javax.swing.JMenuItem contentsMenuItem;
    private javax.swing.ButtonGroup decorationRotationButtonGroup;
    private javax.swing.JList decorationsList;
    private javax.swing.JPanel decorationsPanel;
    private javax.swing.JRadioButton degree0RadioButton;
    private javax.swing.JRadioButton degree180RadioButton;
    private javax.swing.JRadioButton degree270RadioButton;
    private javax.swing.JRadioButton degree90RadioButton;
    private javax.swing.JMenuItem exitMenuItem;
    private javax.swing.JMenu fileMenu;
    private javax.swing.JPanel heightPanel;
    private javax.swing.JSpinner heightSpinner;
    private javax.swing.JToggleButton heightToggleButton;
    private javax.swing.JMenu helpMenu;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JSeparator jSeparator1;
    private javax.swing.JSeparator jSeparator2;
    private javax.swing.JMenuBar menuBar;
    private javax.swing.JMenuItem newMenuItem;
    private javax.swing.JMenuItem openMenuItem;
    private javax.swing.JMenu optionsMenu;
    private javax.swing.JMenuItem previewMenuItem;
    private javax.swing.JMenu renderMenu;
    private javax.swing.JFileChooser saveFileChooser;
    private javax.swing.JMenuItem saveMenuItem;
    private javax.swing.JScrollPane scrollPane;
    private javax.swing.JRadioButton sideRadioButton;
    private javax.swing.JList texturesList;
    private javax.swing.JPanel texturesPanel;
    private javax.swing.JPanel toolsPanel;
    private javax.swing.JRadioButton topRadioButton;
    private javax.swing.ButtonGroup topSideButtonGroup;
    // End of variables declaration//GEN-END:variables
    
}
